﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using Workflow.Alerts.DAL;
using System.Text;
using System.Globalization;
using workflow.Dal;

namespace Workflow.Alerts
{
    public class ListPresenter : ActionPresenter
    {
        #region Fields
        protected MainListDAL model;
        #endregion

        #region Constructors
        public ListPresenter(ISessionProvider session)
            : base(null, session)
        {

        }

        internal ListPresenter(IView view, ISessionProvider session)
            : base(view, session)
        {

        }
        #endregion

        #region Methods
        protected List<WorkflowEnums.Status> GetScreenStatus(string item)
        {
            var statusList = new List<WorkflowEnums.Status>();

            if (CurrentUser.Type == WorkflowEnums.UserType.Municipality)
            {
                switch (item)
                {
                    case WorkflowConstants.NewAlerts:
                        statusList.Add(WorkflowEnums.Status.Sent);
                        break;
                    case WorkflowConstants.InProgress:
                        statusList.Add(WorkflowEnums.Status.Approved);
                        statusList.Add(WorkflowEnums.Status.PartiallyApproved);
                        statusList.Add(WorkflowEnums.Status.Declined);// Municipality do not accept work from Network operator
                        break;
                    case WorkflowConstants.Executed:
                        statusList.Add(WorkflowEnums.Status.Executed4Municipality);
                        statusList.Add(WorkflowEnums.Status.Executed4Contractor);
                        break;
                    case WorkflowConstants.Invoices:
                        statusList.Add(WorkflowEnums.Status.Accepted);
                        statusList.Add(WorkflowEnums.Status.AcceptedPartially);
                        break;
                    case WorkflowConstants.Logged:
                        statusList.Add(WorkflowEnums.Status.Rejected);
                        statusList.Add(WorkflowEnums.Status.Accepted);
                        statusList.Add(WorkflowEnums.Status.AcceptedPartially);
                        statusList.Add(WorkflowEnums.Status.Retracted);
                        break;

                }
            }
            else if (CurrentUser.Type == WorkflowEnums.UserType.NetworkOperator)
            {
                switch (item)
                {
                    case WorkflowConstants.Queued:
                        statusList.Add(WorkflowEnums.Status.Created);
                        break;
                    case WorkflowConstants.Sent:
                        statusList.Add(WorkflowEnums.Status.Sent);
                        break;
                    case WorkflowConstants.InProgress:
                        statusList.Add(WorkflowEnums.Status.Approved);
                        statusList.Add(WorkflowEnums.Status.PartiallyApproved);
                        statusList.Add(WorkflowEnums.Status.Declined);
                        break;
                    case WorkflowConstants.Executed:
                        statusList.Add(WorkflowEnums.Status.Executed4Municipality);
                        statusList.Add(WorkflowEnums.Status.Accepted);
                        statusList.Add(WorkflowEnums.Status.AcceptedPartially);
                        break;
                    case WorkflowConstants.Logged:
                        statusList.Add(WorkflowEnums.Status.Rejected);
                        statusList.Add(WorkflowEnums.Status.Accepted);
                        statusList.Add(WorkflowEnums.Status.AcceptedPartially);
                        statusList.Add(WorkflowEnums.Status.Retracted);
                        break;
                }
            }
            else
            {
                //Contractor
            }

            return statusList;
        }

        protected DataRow[] ApplyFilter(EstateDataSet.ListAlertDataTable list)
        {
            if (Filters == null)
                return list.Select();

            //apply check boxes
            var filter = new StringBuilder();
            if (Filters.SelectedAlertType != null && Filters.SelectedAlertType.Count > 0)
            {
                string[] intArrayStr = Array.ConvertAll<int, string>(Filters.SelectedAlertType.ToArray(), new Converter<int, string>(Convert.ToString));
                string result = String.Join(",", intArrayStr);
                filter.AppendFormat("alertType in ({0})", result);
            }
            if (Filters.SelectedActivitiyType != null && Filters.SelectedActivitiyType.Count > 0)
            {
                string[] intArrayStr = Array.ConvertAll<int, string>(Filters.SelectedActivitiyType.ToArray(), new Converter<int, string>(Convert.ToString));
                string result = String.Join(",", intArrayStr);
                if (filter.Length > 0)
                    filter.Append(" AND ");
                filter.AppendFormat("activityType in ({0})", result);
            }
            if (Filters.SelectedNetworkOperators != null && Filters.SelectedNetworkOperators.Count > 0)
            {
                string[] intArrayStr = Array.ConvertAll<int, string>(Filters.SelectedNetworkOperators.ToArray(), new Converter<int, string>(Convert.ToString));
                string result = String.Join(",", intArrayStr);
                if (filter.Length > 0)
                    filter.Append(" AND ");
                filter.AppendFormat("networkopId in ({0})", result);
            }

            if (Filters.SelectedMunicipalities != null && Filters.SelectedMunicipalities.Count > 0)
            {
                string[] intArrayStr = Array.ConvertAll<int, string>(Filters.SelectedMunicipalities.ToArray(), new Converter<int, string>(Convert.ToString));
                string result = String.Join(",", intArrayStr);
                if (filter.Length > 0)
                    filter.Append(" AND ");
                filter.AppendFormat("municipalityid in ({0})", result);
            }
            if (Filters.SelectedStatuses != null && Filters.SelectedStatuses.Count > 0)
            {
                string[] intArrayStr = Array.ConvertAll<int, string>(Filters.SelectedStatuses.ToArray(), new Converter<int, string>(Convert.ToString));
                string result = String.Join(",", intArrayStr);
                if (filter.Length > 0)
                    filter.Append(" AND ");
                filter.AppendFormat("currentStatus in ({0})", result);
            }

            if (Filters.Dates != null && Filters.Dates.Count > 0)
            {
                foreach (var item in Filters.Dates)
                {
                    string action = (item.Key.StartsWith("from_")) ? ">=" : "<=";
                    string column = item.Key.Substring(item.Key.IndexOf('_') + 1);
                    if (list.Columns.Contains(column))
                    {
                        if (filter.Length > 0)
                            filter.Append(" AND ");
                        filter.AppendFormat("{0} {1} #{2}#", column, action, item.Value.ToString(DateTimeFormatInfo.InvariantInfo));
                    }
                }
            }
            if (Filters.SelectedContractor != null)
            {
                if (filter.Length > 0)
                    filter.Append(" AND ");
                filter.AppendFormat("contractorid = ({0})", Filters.SelectedContractor.Value);
            }

            var resultList = (EstateDataSet.ListAlertRow[])list.Select(filter.ToString(), "estimatestartdate desc");

            if (Filters.IsHerstel != null && Filters.IsHerstel)
            {
                using (WorkflowEntitySet context = new WorkflowEntitySet())
                {
                    var alerts = context.Alert.Include("AlertMaterials").Where(a => a.archived == true && a.AlertMaterials.Where(am => am.uitstel == true).Any()).ToList();

                    List<EstateDataSet.ListAlertRow> herstelList = new List<EstateDataSet.ListAlertRow>();
                    foreach(EstateDataSet.ListAlertRow rec in resultList)
                    {
                        if(alerts.Where(a=>a.id==rec.id).Any())
                        {
                            herstelList.Add(rec);
                        }
                    }

                    return herstelList.ToArray();
                }
               
            }

            return resultList;
        }

        protected EstateDataSet.ListAlertDataTable UpdateListWithTemporaryChanges(EstateDataSet.ListAlertDataTable alerts)
        {
            var tempChanges = TempChanges;
            if (tempChanges.Any())
            {
                foreach (Alert tempAlert in tempChanges)
                {
                    var alert = alerts.FindByid(tempAlert.id);
                    if (alert != null)
                    {
                        alert.currentstatus = tempAlert.currentstatus;
                    }
                }
            }

            return alerts;
        }

        protected virtual void SetWorkflowFilter(string item)
        {
            List<WorkflowEnums.Status> statusList = GetScreenStatus(item);
            workflowFilter = new WorkflowFilter
            {
                Status = statusList,
            };
            if (Session["searchCriteria"] != null)
                workflowFilter.Search = Session["searchCriteria"].ToString();
            if (CurrentUser.Type == WorkflowEnums.UserType.Municipality)
                workflowFilter.MunicipalityId = CurrentUser.TypeId;
            else if (CurrentUser.Type == WorkflowEnums.UserType.NetworkOperator)
                workflowFilter.NetworkOperatorId = CurrentUser.TypeId;
            else if (CurrentUser.Type == WorkflowEnums.UserType.Contractor)
                workflowFilter.ContractorId = CurrentUser.TypeId;
            if (WorkflowConstants.Logged.ToString() == item)
            {
                workflowFilter.Archive = true;
            }
        }

        protected void ResetChanges(string item)
        {
            if (Session[WorkflowConstants.CurrentItem] == null ||
                Session[WorkflowConstants.CurrentItem] as String != item)
            {
                Session[WorkflowConstants.CurrentItem] = item;
                Changes = null;
                Filters = null;
                TempChanges = null;
            }

            if (item != "Search")
            {
                Session["searchCriteria"] = null;
            }
        }

        protected virtual void view_OnLoad()
        {
            string item = Utils.Utils.GetCurrentItem();
            ResetChanges(item);
            SetWorkflowFilter(item);
        }

        protected DataRow[] GetList()
        {
            EstateDataSet.ListAlertDataTable list = model.GetAlerts(new WorkflowFilterSql(workflowFilter));
            EstateDataSet.ListAlertDataTable modifiedList = UpdateListWithTemporaryChanges(list);
            return ApplyFilter(modifiedList);
        }

        #endregion

        #region Properties
        protected WorkflowFilter workflowFilter { get; set; }
        #endregion
    }
}
